package cn.tedu.charging.order.websocket;

import cn.tedu.charging.common.protocol.WebSocketMessage;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 容器bean对象 不是单例的,可以理解每次连接建立,容器中都会重新创建一个
 * WebSocketServer
 */
@Component
@ServerEndpoint("/ws/server/{userId}")
@Slf4j
public class WebSocketServer {
    //websocketServer对象 如果可以实现ws通信逻辑需要我们了解其所有的通信
    //调用的终端方法
    //创建一个静态变量(如果是动态就无法获取session)
    private static Map<Integer,Session> sessionMap=new ConcurrentHashMap<>();
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") Integer userId){
        //连接开始建立
        log.info("开始建立连接,sessionId:{},入参userId:{}",session.getId(),userId);
        //给用户推送一个消息 欢迎您连接访问
        String msg="欢迎您访问";
        try{
            session.getBasicRemote().sendText(msg);
        }catch (IOException e){
            e.printStackTrace();
        }
        //存储注册映射数据
        sessionMap.put(userId,session);
    }

    @OnClose
    public void onClose(Session session,@PathParam("userId")Integer userId){
        log.info("连接关闭,sessionId:{}",session.getId());
        sessionMap.remove(userId);
    }

    @OnError
    public void onError(Throwable throwable,Session session){
        log.error("连接错误,sessionId:{}",session.getId(),throwable);
    }

    //客户端可以向服务端发送消息
    @OnMessage
    public void onMessage(String message,Session session){
        log.info("收到消息:{},sessionId:{}",message,session.getId());
        String msg="欢迎您发消息";
        try{
            session.getBasicRemote().sendText(msg);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /*public void sendMsgToUser(Integer userId,String msg){
        //1.使用userId 获取session对象
        Session session = sessionMap.get(userId);
        //2.如果session不为空 才能发送消息
        if (session==null){
            //目标用户没有建立过连接
            log.error("目标用户没有建立过连接");
        }else{
            try{
                session.getBasicRemote().sendText(msg);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }*/
    //在测试案例中 发送消息是字符串,在项目中希望发送一个对象 需要经过json字符串做序列化
    public void sendMsgToUser(Integer userId, WebSocketMessage message){
        //序列化过程
        String jsonData = JSON.toJSONString(message);
        Session session = sessionMap.get(userId);
        //2.如果session不为空 才能发送消息
        if (session==null){
            //目标用户没有建立过连接
            log.error("目标用户没有建立过连接");
        }else{
            try{
                session.getBasicRemote().sendText(jsonData);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
